#include "modes.h"
#include "sm4.h"

void sm4_ede_set_encrypt_key(sm4_ede_key_t*      key,
                             const unsigned char user_key[48])
{
    sm4_set_encrypt_key(&key->k1, user_key);
    sm4_set_decrypt_key(&key->k2, user_key + 16);
    sm4_set_encrypt_key(&key->k3, user_key + 32);
}

void sm4_ede_set_decrypt_key(sm4_ede_key_t*      key,
                             const unsigned char user_key[48])
{
    sm4_set_decrypt_key(&key->k1, user_key + 32);
    sm4_set_encrypt_key(&key->k2, user_key + 16);
    sm4_set_decrypt_key(&key->k3, user_key);
}

void sm4_ede_encrypt(const unsigned char in[16], unsigned char out[16],
                     const sm4_ede_key_t* key)
{
    sm4_encrypt(in, out, &key->k1);
    sm4_encrypt(out, out, &key->k2);
    sm4_encrypt(out, out, &key->k3);
}

void sm4_ede_ecb_encrypt(const unsigned char* in, unsigned char* out,
                         const sm4_ede_key_t* key, int enc)
{
    (void)enc;
    sm4_ede_encrypt(in, out, key);
}

void sm4_ede_cbc_encrypt(const unsigned char* in, unsigned char* out,
                         size_t len, const sm4_ede_key_t* key,
                         unsigned char* iv, int enc)
{
    if (enc)
        CRYPTO_cbc128_encrypt(in, out, len, key, iv,
                              (block128_f)sm4_ede_encrypt);
    else
        CRYPTO_cbc128_decrypt(in, out, len, key, iv,
                              (block128_f)sm4_ede_encrypt);
}

void sm4_ede_cfb128_encrypt(const unsigned char* in, unsigned char* out,
                            size_t len, const sm4_ede_key_t* key,
                            unsigned char* iv, int* num, int enc)
{
    CRYPTO_cfb128_encrypt(in, out, len, key, iv, num, enc,
                          (block128_f)sm4_ede_encrypt);
}

void sm4_ede_ofb128_encrypt(const unsigned char* in, unsigned char* out,
                            size_t len, const sm4_ede_key_t* key,
                            unsigned char* iv, int* num)
{
    CRYPTO_ofb128_encrypt(in, out, len, key, iv, num,
                          (block128_f)sm4_ede_encrypt);
}

void sm4_ede_ctr128_encrypt(const unsigned char* in, unsigned char* out,
                            size_t len, const sm4_ede_key_t* key,
                            unsigned char* iv,
                            unsigned char  ecount_buf[SM4_BLOCK_SIZE],
                            unsigned int*  num)
{
    CRYPTO_ctr128_encrypt(in, out, len, key, iv, ecount_buf, num,
                          (block128_f)sm4_ede_encrypt);
}

int sm4_ede_wrap_key(sm4_ede_key_t* key, const unsigned char* iv,
                     unsigned char* out, const unsigned char* in,
                     unsigned int inlen)
{
    return CRYPTO_128_wrap(key, iv, out, in, inlen,
                           (block128_f)sm4_ede_encrypt);
}

int sm4_ede_unwrap_key(sm4_ede_key_t* key, const unsigned char* iv,
                       unsigned char* out, const unsigned char* in,
                       unsigned int inlen)
{
    return CRYPTO_128_unwrap(key, iv, out, in, inlen,
                             (block128_f)sm4_ede_encrypt);
}
